package org.flexthinker.module.impl
{
    import org.flexthinker.module.Descriptor;

    import flash.display.DisplayObject;
    import flash.events.Event;
    import flash.events.IEventDispatcher;

    import mx.core.IFlexModuleFactory;
    import mx.core.UIComponent;
    import mx.events.Request;
    import mx.events.StyleEvent;
    import mx.logging.ILogger;
    import mx.logging.Log;
    import mx.styles.IStyleManager2;
    import mx.styles.StyleManager;


    public class StylesheetDescriptorLoader extends DescriptorLoaderImpl
    {
        private var log:ILogger = Log.getLogger("org.flexthinker.module.impl.StylesheetDescriptorLoader");

        private var localStyleManager:IStyleManager2;

        public function StylesheetDescriptorLoader(descriptor:Descriptor)
        {
            super(descriptor);
        }

        override public function init(targetObject:UIComponent):void
        {
            super.init(targetObject);

            if (moduleInfo.factory is DisplayObject)
            {
                localStyleManager = getModuleStyleManager2(targetObject);
                var dispatcher:IEventDispatcher = localStyleManager.loadStyleDeclarations2(descriptor.url, true,
                        descriptor.applicationDomain, descriptor.securityDomain);

                dispatcher.addEventListener(StyleEvent.COMPLETE, dispatcher_completeHandler);
                dispatcher.addEventListener(StyleEvent.ERROR, dispatcher_errorHandler);
            }
            else
            {
                throw new Error("Can't load the stylesheet on a non DisplayObject, such as :" + moduleInfo.factory);
            }
        }

        private function getModuleStyleManager2(targetObject:UIComponent):IStyleManager2
        {
            var request:Request = new Request(Request.GET_PARENT_FLEX_MODULE_FACTORY_REQUEST);
            DisplayObject(moduleInfo.factory).dispatchEvent(request);
            var parentModuleFactory:IFlexModuleFactory = request.value as IFlexModuleFactory;

            if (!parentModuleFactory && targetObject)
            {
                parentModuleFactory = targetObject.moduleFactory;
            }

            return StyleManager.getStyleManager(parentModuleFactory);
        }


        private function dispatcher_completeHandler(event:StyleEvent):void
        {
            CONFIG::DEBUG
            {
                log.debug("Style successfully loaded");
            }
            clearLoadingListeners(event);
            dispatchEvent(new Event(Event.COMPLETE));
        }

        private function dispatcher_errorHandler(event:StyleEvent):void
        {
            CONFIG::DEBUG
            {
                log.debug("Error loading style . Reason: " + event.errorText);
            }
            clearLoadingListeners(event);
        }

        private function clearLoadingListeners(event:StyleEvent):void
        {
            IEventDispatcher(event.currentTarget).removeEventListener(StyleEvent.COMPLETE, dispatcher_completeHandler);
            IEventDispatcher(event.currentTarget).removeEventListener(StyleEvent.ERROR, dispatcher_errorHandler);
        }


        override protected function moduleUnloaded():void
        {
            super.moduleUnloaded();
            if (!localStyleManager)
            {
                CONFIG::DEBUG
                {
                    log.debug("Error unloading style. StyleManager was not initialized.");
                }
            }
            if (localStyleManager)
            {
                localStyleManager.unloadStyleDeclarations(descriptor.url, true);
            }

        }
    }
}